package com.oocl.euc.core.maintenance.service;

import com.oocl.euc.common.constant.RoleEnum;
import com.oocl.euc.common.utils.UserContextHolder;
import com.oocl.euc.core.maintenance.model.Function;
import com.oocl.euc.core.maintenance.model.Role;
import com.oocl.euc.core.maintenance.model.Status;
import com.oocl.euc.core.maintenance.repository.FunctionRepository;
import com.oocl.euc.core.maintenance.vo.FunctionAuthVO;
import com.oocl.euc.core.maintenance.vo.FunctionVO;
import com.oocl.euc.core.requestform.model.RequestForm;
import com.oocl.euc.core.requestform.service.RequestFormService;
import com.oocl.euc.framework.base.persistence.IBaseRepository;
import com.oocl.euc.framework.base.service.BaseService;
import com.oocl.euc.framework.common.utils.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


@Service
public class FunctionService extends BaseService<Function, Long> {

    @Autowired
    private FunctionRepository functionRepository;

    @Autowired
    private RoleService roleService;

    @Autowired
    private StatusService statusService;

    @Autowired
    private RequestFormService requestFormService;

    @Override
    protected IBaseRepository<Function, Long> getRepository() {
        return functionRepository;
    }

    protected RoleService getRoleService() {
        return roleService;
    }

    protected RequestFormService getRequestFormService() {
        return requestFormService;
    }

    protected FunctionRepository getFunctionRepository() {
        return functionRepository;
    }

    protected StatusService getStatusService() {
        return statusService;
    }

    public List<FunctionVO> obtainFunctionList(String staffId, String prcrNum) {
        List<Role> roles = getRoleService().findRoleByStaffId(staffId);
        List<Long> roleIds = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(roles)) {
            roles.stream().map(role -> roleIds.add(role.getId())).collect(Collectors.toList());
        }
        RequestForm requestForm = getRequestFormService().findRequestFormByRefNO(prcrNum);
        if (null == requestForm) {
            if(CollectionUtils.isEmpty(roleIds)){
                return convertToFunctionVo(getFunctionRepository().findFunctionNotRelatedWithRole());
            } else {
                return convertToFunctionVo(getFunctionRepository().findFunctionByRoleIds(roleIds));
            }
        }

        String domainId = UserContextHolder.getUserContext().getUserInfo().getDomainId();
        if (CollectionUtils.isNotEmpty(roles)) {
            for (Role role : roles) {
                boolean asRequester = RoleEnum.REQUESTER.value().equalsIgnoreCase(role.getRoleName()) && !requestForm.asReqeuster(domainId);
                boolean canEndorse = RoleEnum.ENDORSER.value().equalsIgnoreCase(role.getRoleName()) && !requestForm.canEndorse(domainId);
                boolean asFirstVerifier = RoleEnum.FIRST_VERIFIER.value().equalsIgnoreCase(role.getRoleName()) && !requestForm.asFirstVerifer
                        (domainId);
                boolean asSecondVerifier = RoleEnum.SECOND_VERIFIER.value().equalsIgnoreCase(role.getRoleName()) && !requestForm.asSecondVerifer
                        (domainId);
                boolean asExecutor = RoleEnum.EXECUTOR.value().equalsIgnoreCase(role.getRoleName()) && !requestForm.asExecutor(domainId);
                if(asRequester || canEndorse || asFirstVerifier || asSecondVerifier || asExecutor){
                    roleIds.remove(role.getId());
                }
            }
        }

        Status status = getStatusService().findByStatusName(requestForm.getRequestStatus());
        if (null == status) {
            if(CollectionUtils.isEmpty(roleIds)) {
                return convertToFunctionVo(getFunctionRepository().findFunctionNotRelatedWithRole());
            }
            return convertToFunctionVo(getFunctionRepository().findFunctionByRoleIds(roleIds));
        }
        if(CollectionUtils.isEmpty(roleIds)){
            return convertToFunctionVo(getFunctionRepository().findFunctionByStatus(status.getId()));
        }
        return convertToFunctionVo(getFunctionRepository().findFunctionByRoleIdsAndStatus(status.getId(), roleIds));
    }

    private List<FunctionVO> convertToFunctionVo(List<Function> functions) {
        List<FunctionVO> functionVOS = new ArrayList<>();
        functions.stream().map(function -> {
            FunctionVO functionVO = new FunctionVO();
            functionVO.setFunctionDesc(function.getFunctionDesc());
            functionVO.setFunctionName(function.getFunctionName());
            functionVO.setRoleRelated(function.isRoleRelated());
            functionVO.setStatusRelated(function.isStatusRelated());
            return functionVOS.add(functionVO);
        }).collect(Collectors.toList());
        return functionVOS;
    }


    public List<FunctionAuthVO> findByFunctionId(Long functionId) {
        Function function = this.findOne(functionId);
        List<FunctionAuthVO> functionAuthVOList = new ArrayList<>();
        if (function != null && (CollectionUtils.isNotEmpty(function.getFunctionAuthSet()))) {
            String functionName = function.getFunctionName();
            String functionDesc = function.getFunctionDesc();
            function.getFunctionAuthSet().forEach(functionAuth -> {
                FunctionAuthVO functionAuthVO = new FunctionAuthVO(functionAuth.getId(),functionId,functionName, functionDesc);
                if (functionAuth.getStatus() != null) {
                    functionAuthVO.setStatusName(functionAuth.getStatus().getStatusName());
                }
                if (functionAuth.getRole() != null) {
                    functionAuthVO.setRoleName(functionAuth.getRole().getRoleName());
                }
                functionAuthVOList.add(functionAuthVO);
            });
        }
        return functionAuthVOList;
    }


}
